/*
 * <h3>Title:wheel-spring-boot-web-starter系统</h3>
 * <p>Copyright (c) 2019, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.core.exception;

import com.wheel.core.result.Result;
import com.wheel.core.utils.Log;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * <dt>Description:AppMessageException</dt>
 * <dd>统一异常处理</dd>
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2019年6月6日 下午6:50:26</i>
 * @since jdk1.7+
 */
public class GlobalAppException extends Exception {

    /**
     *
     */
    private static final long serialVersionUID = 5323035841397869667L;

    // 内部消息代码
    private String code;
    // 对应消息的参数
    private Object[] messageArgs = {};

    /**
     * <dt>Description:AppMessageException</dt>
     * <dd>从代码异常转换成业务异常，自定义消息</dd>
     * <dd>author: wangnaifei@163.com</dd>
     * <dd>version:1.0 <i>2019/12/11 18:41</i></dd>
     *
     * @param code      异常代码
     * @param throwable 异常
     * @param message   异常消息
     * @param args      消息参数
     * @since jdk1.7+
     */
    public GlobalAppException(ResultCode code, Throwable throwable, String message, Object... args) {
        super(message != null ? Log.formatMessage(message, args) : null, throwable);
        setCode(code);
        setMessageArgs(args);
    }

    /**
     * <dt>Description:AppMessageException</dt>
     * <dd>从代码异常转换成业务异常，自定义消息</dd>
     * <dd>author: wangnaifei@163.com</dd>
     * <dd>version:1.0 <i>2019/12/11 18:40</i></dd>
     *
     * @param code    异常代码
     * @param message 异常消息
     * @param args    消息参数
     * @since jdk1.7+
     */
    public GlobalAppException(ResultCode code, String message, Object... args) {
        super(message != null ? Log.formatMessage(message, args) : null);
        setCode(code);
        setMessageArgs(args);
    }

    /**
     * <dt>Description:GlobalAppException</dt>
     * <dd></dd>
     * <dd>author: wangnaifei@163.com</dd>
     * <dd>version:1.0 <i>2020/11/12 20:39</i></dd>
     *
     * @param code      异常代码
     * @param throwable 异常
     * @since jdk1.7+
     */
    protected GlobalAppException(ResultCode code, Throwable throwable) {
        super(throwable);
        setCode(code);
    }

    /**
     * <dt>Description:</dt>
     * <dd>获取异常的堆栈信息</dd>
     * <dd>author wnfbx@163.com</dd>
     * <dd>version 1.0 <i>2019年6月6日 下午7:03:57</i></dd>
     *
     * @param throwable 异常
     * @return {@link String}
     */
    public static String getPrintStackTraceMessage(Throwable throwable) {
        if (throwable == null) {
            return null;
        }
        String r = null;
        try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
            throwable.printStackTrace(pw);
            r = sw.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return r;
    }

    public String getCode() {
        return code;
    }

    public void setCode(ResultCode code) {
        this.code = code.getCode();
    }

    public Object[] getMessageArgs() {
        return messageArgs;
    }

    public void setMessageArgs(Object[] messageArgs) {
        this.messageArgs = messageArgs;
    }

    /**
     * <dt>Description:</dt>
     * <dd>异常输出到前端</dd>
     * <dd>author wnfbx@163.com</dd>
     * <dd>version 1.0 <i>2019年6月5日 下午7:08:52</i></dd>
     *
     * @return {@link Result}
     */

    public Result<Object> asResult(boolean debug) {
        return Result.error(getCode(), getMessage(), debug ? getStackTraceMessage() : null);
    }

    /**
     * <dt>Description:</dt>
     * <dd>获取异常的堆栈信息</dd>
     * <dd>author wnfbx@163.com</dd>
     * <dd>version 1.0 <i>2019年6月5日 下午6:57:07</i></dd>
     *
     * @return {@link String}
     */
    public String getStackTraceMessage() {
        return getPrintStackTraceMessage(this);
    }
}
